/**
 * Obtiene todas las definiciones del mundo almacenadas en la base de datos y los ficheros de definiciones.
 * @memberOf CaboCity.def
 * */
exports.loadDefsFromFiles = function(){
	var api = require('./cabocity.js');
	var fs = require('fs');
	var mysql = api.mysql;
	
	//Load builds definitions.
	var q = "";
	mysql.query(q, function(err, results, fields){
		if(err){
			console.log("Fallo al obtener el listado de definiciones de bodys.");
			throw err;
		}
		Object.each(results, function(bNameDefinition){
			var nb = require('./'+bNameDefinition.name+'.js');
			
			var newBody = new api.def.Build(bNameDefinition.id, bNameDefinition.name);
			newBody.setCheckParams(nb.checkParams);
			newBody.setCheckBuildPosibility(nb.checkBuildPosibility);
			newBody.setBuild(nb.build);
			newBody.setNotBuild(nb.notBuild);
			
			api.def.newBuild( newBody );
		});
	});
	
	var q = "";
	mysql.query(q, function(err, results, fields){
		if(err){
			console.log("Fallo al obtener el listado de definiciones de wt.");
		}
		Object.each(results, function(wtNameDefinition){
			var nwt = require('./'+wtNameDefinition.name+'.js');
			var newWt = new api.def.Wt(wtNameDefinition.id, wtNameDefinition.name);
			api.def.newWt( newWt );
		});
	});
}

exports.def = new Class(/** @lends Core.def# */{
	/**
	 * @class Almacena y carga todas las definiciones.
	 * @constructs
	 * 
	 * @property {CaboCity.t.def.Build[]} build Listado de definiciones de builds.
	 * @property {CaboCity.t.def.Body[]} body Listado de definiciones de bodys.
	 * @property {CaboCity.t.def.Wt[]} wt Listado de definiciones de wts.
	 * 
	 * */
	initialize: function(){
	}
	
	/**
	 * Añade una nueva definición de build.
	 * @public
	 * 
	 * @param {CaboCity.t.def.BuildActions} buildActions Acciones para configurar el nuevo build
	 */
	,addNewBuild: function(buildActions){
		
	}
	
	/**
	 * Añade una nueva definición de body.
	 * @public
	 * 
	 * @param {CaboCity.t.def.BodyActions} bodyActions Acciones para configurar el nuevo body
	 */
	,addNewBody: function(){
		
	}
	
	/**
	 * Añade una nueva definición de wt.
	 * @public
	 * 
	 * @param {CaboCity.t.def.WtActions} wtAction Acciones para configurar el nuevo wt
	 */
	
	,addNewWt: function(){
		
	}
});


exports.def.wtDef = new Class(/** @lends Core.def.wtDef# */{
	/**
	 * @Class Contiene todas las definiciones correspondientes a los wt.
	 * @constructs
	 * */
	initialize: function(){}
	
	/**
	 * Listado de definiciones de wt
	 * @public
	 * @type CaboCity.t.def.wt
	 * */
	,list: []

	/**
	 * Define un nuevo wt y lo añade al listado.
	 * @public
	 * @param {CaboCity.t.def.wt} wtDef
	 * */
	,addNew: function(wtDef){}
});


exports.def.bodyDef = new Class(/** @lends CaboCity.def.bodyDef# */{
	/**
	 * @Class Contiene todas las definiciones correspondientes a los body.
	 * @constructs
	 * */
	initialize: function(){}
	
	/**
	 * Listado de definiciones de bodys
	 * @public
	 * @type CaboCity.t.def.body
	 * */
	,list: []

	/**
	 * Define un nuevo body y lo añade al listado.
	 * @public
	 * @param {CaboCity.t.def.body} bodyDef
	 * */
	,addNew: function(bodyDef){}
});


exports.def.buildDef = new Class(/** @lends CaboCity.def.buildDef# */{
	/**
	 * @Class Contiene todas las definiciones correspondientes a los builds.
	 * @constructs
	 * */
	initialize: function(){}
	
	/**
	 * Listado de definiciones de builds
	 * @public
	 * @type CaboCity.t.def.build[]
	 * */
	,list: []

	/**
	 * Define un nuevo build y lo añade al listado.
	 * @public
	 * @param {CaboCity.t.def.build} buildDef
	 * */
	,addNew: function(buildDef){}
});

/*
buildDef class that loads all definitons related with builds.
The class needs a mysql VALID connection.
*/
var buildDef = new Class({
	initialize: function(mysql){
	
		return null; //deleteme.
		this.mysql = mysql;
		this.buildDef = {};
		
		//Load definitions
		this.loadDefinition();
	}
	,addNewBuild: function(def){
		this.buildDef[def.idbuildDef] = {
			id: def.idbuildDef
			,'name': def.name
			,size: {x: def.sizeX, y: def.sizeY}
		}
	}
	
	//Load all build definitions from database.
	,loadDefinition: function(){
		var q = "SELECT * FROM buildDef";
		
		var r;
		this.mysql.query(q, function(err, results, fields){
			if(err){
				console.log("Fallo en la base de datos. No se pudieron cargar las definiciones de los build.");
				throw err;
			}
			r = results;
		});
	}
	,getDef: function(){
		return this.buildDef;
	}
});

/*
bodydef class that loads all definitons related with bodys.
The class needs a mysql VALID connection.
*/
var bodyDef = new Class({
	initialize: function(mysql){
		return; //delete me;
		this.mysql = mysql;
		this.bodyDef = {};
		
		//Load definitions
		this.loadDefinition();
	}
	,addNewBody: function(def){
		this.bodyDef[def.idbodyDef] = {
			id: def.idbodyDef,
			'name' : def.name
		}
	}
	,addNewInteraction: function(interaction){
		if( !(interaction.type == 'leave' || interaction.type == 'enter' || interaction.type == 'visit') )
			throw "Error en la interaccion";
		if( !buildDef[interaction.idbuildDef] ) throw "El builddef no existe.";
		if( !this.bodyDef[interaction.idbodyDef] ) throw "El bodydef no existe.";
		if(typeof( funcs[interaction.func] ) != "function") throw "La funcion de la interacción no existe."
		
		var interaction = {
			idbodyDef: interaction.idbuildDef
			,idbodyDef: interaction.idbodyDef
			,type: interaction.type
			,func: funcs[interaction.func]
		};
		
		buildDef[idbuildDef].interaction[type] = interaction;
		this.bodyDef[idbodyDef].interaction[type] = interaction;
	}
	,loadDefinition: function(){
	
		//Load bodys.
		var q = "";
		this.mysql.query(q, function(err, results, fields){
			if(err){
				console.log("Fallo en la base de datos. No se pudieron cargar las definiciones de los body.");
				throw err;
			}
			Object.each(results, function(res){
				this.addNewBody(res);
			}.bind(this));
		}.bind(this));
		
		//Load interactions with builds.
		var q = "";
		this.mysql.query(q, function(err, results, fields){
			if(err){
				console.log("Fallo en la base de datos. No se pudieron cargar las interacciones.");
				throw err;
			}
			Object.each(results, function(res){
				this.addNewBody(res);
			}.bind(this));
		});
	}
	,getDef: function(){
		return this.buildDef;
	}
});

/*
Resource class that loads all definitons related with resources.
The class needs a mysql VALID connection.
*/
var resourceDef = new Class({
	initialize: function(mysql){
	
		return null; //deleteme.
		this.mysql = mysql;
		this.resourceDef = {};
		
		//Load definitions
		this.loadDefinition();
	}
	,addNewResource: function(def){
		this.resourceDef[def.idresourceDef] = {
			id: def.idresourceDef
		}
	}
	
	//Add new can_have relation
	,addNewCan_have: function(def){
		if( !buildDef[def.idbuildDef] ) throw "El builddef no existe.";
		if( !this.resourceDef[def.idresourceDef] ) throw "El recurso no existe.";
		
		var can_have =  {
			idbuildDef: def.idbuildDef
			,idresourceDef: def.idresourceDef
		};
		this.resourceDef[def.idresourceDef].can_have = can_have;
		buildDef[def.idbuildDef].can_have = can_have;
	}
	
	//Add can_carry relation
	,addNewCan_carry: function(def){
		if( !bodyDef[def.idbodyDef] ) throw "El bodydef no existe";
		if( !this.resourceDef[def.idresourceDef] ) throw "El recurso no existe.";
		
		var can_carry = {
			idresourceDef : def.idresourceDef
			,idbodyDef : def.idbodyDef
		}
		this.resourceDef[def.idresourceDef].can_carry = can_carry;
		bodyDef[def.idbodyDef].can_carry = can_carry;
	}
	
	//Load all build definitions from database.
	,loadDefinition: function(){
		//Load resource Definitions.
		var q = "";
		this.mysql.query(q, function(err, results, fields){
			if(err){
				console.log("Fallo en la base de datos. No se pudieron cargar las definiciones de los build.");
				throw err;
			}
			Object.each(results, function(res){
				this.addNewResource(res);
			}.bind(this));
		}.bind(this));
		
		//Load can_have relations.
		var q = "";
		this.mysql.query(q, function(err, results, fields){
			if(err){
				console.log("Fallo en la base de datos. No se pudieron cargar las relaciones de can_have.");
				throw err;
			}
			Object.each(results, function(res){
				this.addNewCan_have(res);
			}.bind(this));
		}.bind(this));
		
		//Load can_carry relations.
		var q = "";
		this.mysql.query(q, function(err, results, fields){
			if(err){
				console.log("Fallo en la base de datos. No se pudieron cargar las relaciones de can_carry.");
				throw err;
			}
			Object.each(results, function(res){
				this.addNewCan_carry(res);
			}.bind(this));
		}.bind(this));
		
	}
	,getDef: function(){
		return this.resourceDef;
	}
});

/*
bodydef class that loads all definitons related with bodys.
The class needs a mysql VALID connection.
*/
var wtd = new Class({
	initialize: function(mysql){
		return; //delete me;
		this.mysql = mysql;
		this.wtdef = {};
		
		//Load definitions
		this.loadDefinition();
	}
	,addNewWorldThingDef: function(def){
		this.resourceDef[def.idworldThingDef] = {
			id: def.idworldThingDef,
			'name' : def.name
		}
	}
	,loadDefinition: function(){
		//Load WorldThing definitions.
		var q = "";
		this.mysql.query(q, function(err, results, fields){
			if(err){
				console.log("Fallo en la base de datos. No se pudieron cargar las definiciones de los world Thing.");
				throw err;
			}
			Object.each(results, function(res){
				this.addNewWorldThingDef(res);
			}.bind(this));
		}.bind(this));
	}
	,getDef: function(){
		return this.wtdef;
	}
});

/*
After execute function it will return a object with all definitions
*/
exports.load = function(mysql){
	return {
		buildDef : (new buildDef(mysql)).getDef()
		,bodyDef : (new bodyDef(mysql)).getDef()
	};
}

exports.resourceDef;
